package com.newbee.service;

import com.newbee.aop.SkipTrace;
import com.newbee.builder.TraceNodeBuilder;
import com.newbee.model.MqCallbackBaseMessage;
import com.newbee.model.TraceContext;
import com.newbee.model.TraceNode;
import com.newbee.model.TraceNodeStack;
import com.newbee.utils.TraceContextHolder;
import com.newbee.utils.TraceNodeStackHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.CompletableFuture;

/**
 * 模拟发起调用并触发回调的服务
 */
@Service
@Slf4j
public class MockCallService {

    // 本地回调接口地址（Controller层的接收地址）
    private static final String LOCAL_CALLBACK_URL = "http://127.0.0.1:8080/visual-link-tracking/mock/mq/callback/receive";

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private TraceNodeBuilder traceNodeBuilder;

    /**
     * 发起本地HTTP调用（模拟发送MQ消息，后续触发回调）
     */
    @SkipTrace
    public void sendAndCallback(String content) {
        // 1. 先获取主线程的TraceContext（此时处于主线程中，可直接获取）
        TraceContext traceContext = TraceContextHolder.getOrInit(false);
        String currentTraceId = traceContext.getTraceId();

        // 构造异步节点
        TraceNode asyncNode = traceNodeBuilder.buildAsyncNode(traceContext);

        // 将异步节点添加到主线程的链路中
        TraceNodeStack stack = TraceNodeStackHolder.getOrInit(null);
        stack.relatedAsyncChildNodes(asyncNode);

        String asyncRootNodeId = asyncNode.getNodeId();

        log.info("模拟MQ，当前traceId={}, asyncRootNodeId={}", currentTraceId, asyncRootNodeId);

        // 2. 构建模拟MQ消息（携带traceId）
        MqCallbackBaseMessage message = new MqCallbackBaseMessage();
        message.setTraceId(currentTraceId);
        message.setAsyncRootNodeId(asyncRootNodeId);
        message.setContent(content);

        // 3. 设置请求头（JSON格式）
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<MqCallbackBaseMessage> request = new HttpEntity<>(message, headers);

        // 3. 异步发起HTTP调用（模拟MQ异步投递，不阻塞主线程）
        CompletableFuture.runAsync(() -> {
            try {
                // 发起同步调用（模拟为模拟MQ的异步性，实际MQ是投递后立即返回）
                String response = restTemplate.postForObject(LOCAL_CALLBACK_URL, request, String.class);
                log.info("异步异步回调处理完成，响应：{}", response);
            } catch (Exception e) {
                log.error("异步异步回调失败", e);
            }
        });

        log.info("模拟MQ消息消息已投递（异步处理中）");
    }
}
